import type { ComponentStyleIdType } from '../types/interfaces'
import { createStandardStyleTag } from '../lib/style_injector'
import { ComponentStyleId, logger } from '../types/constants'

export class StyleManager {
  readonly id: string = 'style_manager'
  readonly styleId: string = ComponentStyleId[this.name]
  private static instance: StyleManager
  private styleElement: HTMLStyleElement | undefined
  registeredStyles: Map<string, string> = new Map()

  get name(): ComponentStyleIdType {
    return 'StyleManager'
  }

  private constructor() {
    this.createStyleTag()
  }

  createStyleTag(): void {
    this.styleElement = createStandardStyleTag(this.styleId, '', { allowEmpty: true })!
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): StyleManager {
    if (!StyleManager.instance) {
      StyleManager.instance = new StyleManager()
    }
    return StyleManager.instance
  }

  /**
   * 注册单个样式
   * @param styleId 样式 ID
   * @param cssContent 样式内容
   * @param deferUpdate 是否延迟更新（用于批量操作）
   * @param skipUpdate 是否跳过更新
   * @param dynamic 是否为动态样式
   */
  public registerStyle(styleId: string, cssContent: string, deferUpdate: boolean = false, skipUpdate: boolean = false, dynamic: boolean = false): void {
    if (this.hasStyle(styleId)) {
      if (skipUpdate && !dynamic) {
        return
      }

      if (!skipUpdate) {
        logger.warn(`[StyleManager] 样式 ${styleId} 已存在，将被覆盖`)
      }
    }

    this.registeredStyles.set(styleId, cssContent)
    if (dynamic) {
      this.registeredStyles.set(`${styleId}-dynamic-${Date.now()}`, cssContent)
    }

    if (!deferUpdate) {
      this.updateStyle()
    }
  }

  /**
   * 批量注册样式
   * @param styles 样式键值对对象或 Map
   */
  public batchRegisterStyles(styles: Record<string, string> | Map<string, string>): void {
    const entries = styles instanceof Map ? styles.entries() : Object.entries(styles)

    for (const [styleId, cssContent] of entries) {
      this.registerStyle(styleId, cssContent, true) // 延迟更新
    }

    this.updateStyle() // 批量完成后统一更新
  }

  /**
   * 移除单个样式
   * @param styleId 样式 ID
   * @param deferUpdate 是否延迟更新
   */
  public unregisterStyle(styleId: string, deferUpdate = false): void {
    if (this.registeredStyles.delete(styleId) && !deferUpdate) {
      this.updateStyle()
    }
  }

  /**
   * 批量移除样式
   * @param styleIds 样式 ID 数组
   */
  public batchUnregisterStyles(styleIds: string[]): void {
    let changed = false

    for (const styleId of styleIds) {
      if (this.registeredStyles.delete(styleId)) {
        changed = true
      }
    }

    if (changed) {
      this.updateStyle()
    }
  }

  /**
   * 更新全局样式
   */
  private updateStyle(): void {
    if (!this.styleElement)
      return

    let combinedStyles = ''
    this.registeredStyles.forEach((css) => {
      combinedStyles += `${css}\n`
    })
    this.styleElement.textContent = combinedStyles
    // logger.info(`[${this.name}] 已更新 ${this.registeredStyles.size} 个样式`, this.getRegisteredStyleIds())
  }

  /**
   * 获取当前所有样式 ID
   */
  public getRegisteredStyleIds(): string[] {
    return Array.from(this.registeredStyles.keys())
  }

  /**
   * 检查样式是否存在
   * @param styleId 样式ID
   */
  public hasStyle(styleId: string): boolean {
    return this.registeredStyles.has(styleId)
  }

  /**
   * 销毁管理器
   */
  public destroy(): void {
    this.registeredStyles.clear()
    this.styleElement?.remove()
    StyleManager.instance = null!
  }
}
